package com.erpanderp.wam.usm.view.timesheet;

import java.io.Serializable;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.primefaces.context.RequestContext;

import com.erpanderp.wam.ac.model.entity.project.ProjectAssignmentDetail;
import com.erpanderp.wam.adm.model.entity.Role;
import com.erpanderp.wam.adm.model.service.RolePermissionDAO;
import com.erpanderp.wam.usm.model.entity.projectandassignment.Project;
import com.erpanderp.wam.usm.model.entity.timesheet.ProjectAssignmentTimesheetDetail;
import com.erpanderp.wam.usm.model.entity.timesheet.Timesheet;
import com.erpanderp.wam.usm.model.entity.timesheet.TimesheetDetail;
import com.erpanderp.wam.usm.model.entity.user.EmployeeAndReporting;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.usm.model.service.projectandassignment.EmployeeProjectDAO;
import com.erpanderp.wam.usm.model.service.timesheet.ProjectAssignmentTimesheetDetailDAO;
import com.erpanderp.wam.usm.model.service.timesheet.TimesheetDAO;
import com.erpanderp.wam.usm.model.service.timesheet.TimesheetDetailDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeAndReportingDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeRoleDAO;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMUtil;
import com.sun.org.apache.bcel.internal.generic.NEW;

@ManagedBean
@ViewScoped
public class ViewTimesheetsBean implements Serializable {

	HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
			.getExternalContext().getSession(true);
	private WAMUser wamUser = (WAMUser) session
			.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);
	private TimeZone defaultTimeZone = TimeZone.getDefault();
	
	private static final long serialVersionUID = 1L;

	private Map<String, Integer> monthsMap = CommonLookup.getMonths();
	private Map<String, Integer> yearsMap = WAMUtil.getLastSixYears();
	private Integer selectedMonth;
	private List<Timesheet> timesheets = new ArrayList<Timesheet>();
	private List<TimesheetDetail> timesheetDetails = new ArrayList<TimesheetDetail>();
	private Integer selectedYear;
	private String employeeCode;
	private String employeeName;
	private Timesheet selectedTimesheet;
	String monthNames[] = new DateFormatSymbols().getMonths();

	TimesheetDAO timesheetDAO = new TimesheetDAO();
	TimesheetDetailDAO timesheetDetailDAO = new TimesheetDetailDAO();
	EmployeeRoleDAO employeeRoleDAO = new EmployeeRoleDAO();
	private boolean HAS_VIEW_EMPLOYEE_TIMESHEET;
	RolePermissionDAO rolePermissionDAO = new RolePermissionDAO();
	private boolean TIMESHEET_FOUND;
	private boolean IN_PROJECT;
	private String approvalComment;

	public ViewTimesheetsBean() {
		Calendar calendar = Calendar.getInstance();
		selectedMonth = calendar.get(Calendar.MONTH);
		selectedYear = calendar.get(Calendar.YEAR);

		if (rolePermissionDAO.hasRolePermission(
				CommonLookup.PERMISSION_VIEW_EMPLOYEE_TIMESHEET, wamUser
						.getEmployee().getEmployeeId())) {
			HAS_VIEW_EMPLOYEE_TIMESHEET = true;
		} else {
			HAS_VIEW_EMPLOYEE_TIMESHEET = false;
		}
	}

	public void searcActionListener(ActionEvent e) {
		System.out.println("Listener...");
		Role loginUserRole = employeeRoleDAO.getRoleByEmployeeId(wamUser
				.getEmployee().getEmployeeId());
		if (HAS_VIEW_EMPLOYEE_TIMESHEET) {//For additional timesheet viewer like HR
			setTimesheets(timesheetDAO.getTimesheets(selectedYear,
					monthNames[selectedMonth], employeeCode, employeeName));
		} else {//For approvers
			setTimesheets(timesheetDAO.getTimesheets(selectedYear,
					monthNames[selectedMonth], employeeCode, employeeName,
					wamUser.getEmployee().getEmployeeId()));
		}

		if (timesheets != null && timesheets.size() > 0) {
			System.out.println("TIMESHEET FOUND");
			TIMESHEET_FOUND = true;
		} else {
			TIMESHEET_FOUND = false;
		}
	}

	public void selectTimesheetActionListener(ActionEvent e) {
		selectedTimesheet = (Timesheet) e.getComponent().getAttributes().get("selectedTimesheet");
		timesheetDetails = timesheetDetailDAO.getTimesheetDetails(selectedTimesheet.getTimesheetId());

		EmployeeProjectDAO employeeProjectDAO = new EmployeeProjectDAO();
		EmployeeAndReportingDAO employeeAndReportingDAO = new EmployeeAndReportingDAO();
		EmployeeAndReporting employeeAndReporting = employeeAndReportingDAO.getEmployeeReportingDetail(selectedTimesheet.getEmployee().getEmployeeId());

		// identify whether user is in project or not
		List<Project> projects = employeeProjectDAO.getAllProjects(selectedTimesheet.getEmployee().getEmployeeId());
		if (employeeAndReporting.getProject() != null && !employeeAndReporting.getProject().equals(CommonLookup.PROJECT_KA) && projects != null && projects.size() > 0) {
			IN_PROJECT = true;
		}else{
			IN_PROJECT = false;
		}

		Collections.sort(timesheetDetails);
	}

	public void postProcessXLS(Object document) {
		HSSFWorkbook wb = (HSSFWorkbook) document;
		HSSFSheet sheet = wb.getSheetAt(0);
		HSSFRow header = sheet.getRow(0);

		HSSFCellStyle cellStyle = wb.createCellStyle();
		cellStyle.setFillForegroundColor(HSSFColor.ORANGE.index);
		cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

		for (int i = 0; i < header.getPhysicalNumberOfCells(); i++) {
			HSSFCell cell = header.getCell(i);
			cell.setCellStyle(cellStyle);
		}
		
		if(IN_PROJECT){
			ProjectAssignmentTimesheetDetailDAO projectAssignmentTimesheetDetailDAO = new ProjectAssignmentTimesheetDetailDAO();
			
			for (Iterator<Row> rit = sheet.rowIterator(); rit.hasNext(); ) {
			      Row row = rit.next();
			      int counter = 0;
			      for (Iterator<Cell> cit = row.cellIterator(); cit.hasNext(); ) {
			        Cell cell = cit.next();
			        
			        if(cell.getColumnIndex() == 2 && cell.getStringCellValue().equals("Activity")){
			        	TimesheetDetail timesheetDetail = timesheetDetails.get(counter);
				        List<ProjectAssignmentTimesheetDetail> projectAssignmentTimesheetDetails = projectAssignmentTimesheetDetailDAO.getProjectAssignmentTimesheetDetails(timesheetDetail.getTimesheetdetailId());
				        
				        String cellValue = ""; 
				        for(ProjectAssignmentTimesheetDetail projectAssignmentTimesheetDetail : projectAssignmentTimesheetDetails){
				        	cellValue += (projectAssignmentTimesheetDetail.getEmployeeProject().getProject().getProjectName() + ":\n" +
				        			projectAssignmentTimesheetDetail.getActivity() + "\n");
				        }
				        
				        CellStyle cs = wb.createCellStyle();
				        cs.setWrapText(true);
				        cell.setCellStyle(cs);
				        
				        cell.setCellValue(cellValue);
				        
				        System.out.println(cell.getColumnIndex());
				        System.out.println(cell.getStringCellValue());
				        counter++;	
			        }
			      }
			    }	
		}
		
	}

	public void approveTimesheet(ActionEvent e) {
		if(validate()){
			System.out.println("Approving...");
			selectedTimesheet.setApprovalComment(approvalComment);
			selectedTimesheet.setDateModified(new Date());
			selectedTimesheet.setModifiedBy(wamUser.getEmployee().getFirstName());
			selectedTimesheet.setTimesheetStatus(CommonLookup.TIMESHEET_STATUS_APPROVED);
			if (timesheetDAO.updateTimesheet(selectedTimesheet) != null) {
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								"Timesheet has been approved.", ""));
				RequestContext.getCurrentInstance().addPartialUpdateTarget("viewTimesheetsForm");
				RequestContext.getCurrentInstance().execute("dialog.hide()");
			} else {
				FacesContext
						.getCurrentInstance()
						.addMessage(
								null,
								new FacesMessage(
										FacesMessage.SEVERITY_WARN,
										"ERROR: Timesheet could not be approve. Please try again.",
										""));
			}
		}
	}

	public void rejectTimesheet(ActionEvent e) {
		if(validate()){
			System.out.println("Rejecting...");
			selectedTimesheet.setApprovalComment(approvalComment);
			selectedTimesheet.setDateModified(new Date());
			selectedTimesheet.setModifiedBy(wamUser.getEmployee().getFirstName());
			selectedTimesheet
					.setTimesheetStatus(CommonLookup.TIMESHEET_STATUS_REJECTED);
			if (timesheetDAO.updateTimesheet(selectedTimesheet) != null) {
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								"Timesheet has been rejected.", ""));
				RequestContext.getCurrentInstance().addPartialUpdateTarget("viewTimesheetsForm");
				RequestContext.getCurrentInstance().execute("dialog.hide()");
			} else {
				FacesContext
						.getCurrentInstance()
						.addMessage(
								null,
								new FacesMessage(
										FacesMessage.SEVERITY_WARN,
										"ERROR: Timesheet could not be rejected. Please try again.",
										""));
			}	
		}
		
	}

	private boolean validate(){
		boolean IS_VALID = true;
		if(ValidationUtil.isEmpty(approvalComment, "Comment ", "comment", FacesContext.getCurrentInstance()) != null){
			IS_VALID = false;
		}
		return IS_VALID;
	}
	
	public Map<String, Integer> getMonthsMap() {
		return monthsMap;
	}

	public void setMonthsMap(Map<String, Integer> monthsMap) {
		this.monthsMap = monthsMap;
	}

	public Map<String, Integer> getYearsMap() {
		return yearsMap;
	}

	public void setYearsMap(Map<String, Integer> yearsMap) {
		this.yearsMap = yearsMap;
	}

	public Integer getSelectedMonth() {
		return selectedMonth;
	}

	public void setSelectedMonth(Integer selectedMonth) {
		this.selectedMonth = selectedMonth;
	}

	public List<Timesheet> getTimesheets() {
		return timesheets;
	}

	public void setTimesheets(List<Timesheet> timesheets) {
		this.timesheets = timesheets;
	}

	public Integer getSelectedYear() {
		return selectedYear;
	}

	public void setSelectedYear(Integer selectedYear) {
		this.selectedYear = selectedYear;
	}

	public String getEmployeeCode() {
		return employeeCode;
	}

	public void setEmployeeCode(String employeeCode) {
		this.employeeCode = employeeCode;
	}

	public String getEmployeeName() {
		return employeeName;
	}

	public void setEmployeeName(String employeeName) {
		this.employeeName = employeeName;
	}

	public boolean isTIMESHEET_FOUND() {
		return TIMESHEET_FOUND;
	}

	public void setTIMESHEET_FOUND(boolean tIMESHEET_FOUND) {
		TIMESHEET_FOUND = tIMESHEET_FOUND;
	}

	public Timesheet getSelectedTimesheet() {
		return selectedTimesheet;
	}

	public void setSelectedTimesheet(Timesheet selectedTimesheet) {
		this.selectedTimesheet = selectedTimesheet;
	}

	public List<TimesheetDetail> getTimesheetDetails() {
		return timesheetDetails;
	}

	public void setTimesheetDetails(List<TimesheetDetail> timesheetDetails) {
		this.timesheetDetails = timesheetDetails;
	}

	public TimeZone getDefaultTimeZone() {
		return defaultTimeZone;
	}

	public void setDefaultTimeZone(TimeZone defaultTimeZone) {
		this.defaultTimeZone = defaultTimeZone;
	}

	public WAMUser getWamUser() {
		return wamUser;
	}

	public void setWamUser(WAMUser wamUser) {
		this.wamUser = wamUser;
	}

	public boolean isHAS_VIEW_EMPLOYEE_TIMESHEET() {
		return HAS_VIEW_EMPLOYEE_TIMESHEET;
	}

	public void setHAS_VIEW_EMPLOYEE_TIMESHEET(
			boolean hAS_VIEW_EMPLOYEE_TIMESHEET) {
		HAS_VIEW_EMPLOYEE_TIMESHEET = hAS_VIEW_EMPLOYEE_TIMESHEET;
	}

	public boolean isIN_PROJECT() {
		return IN_PROJECT;
	}

	public void setIN_PROJECT(boolean iN_PROJECT) {
		IN_PROJECT = iN_PROJECT;
	}

	public String getApprovalComment() {
		return approvalComment;
	}

	public void setApprovalComment(String approvalComment) {
		this.approvalComment = approvalComment;
	}
}
